from ortools.sat.python import cp_model


def load_fun_3(job_data, job_type, n, f_p, max_c, tr):
    '''
    装车模型
    :param job_data: EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
    :param job_type: EMS货物形态 0可代表栈板，1代表件箱，2代表gtp
    :param solution_bool_sub_job: 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    :param n: EMS的数量，用于区分EMS和自制
    :param f_p: 浮动参数
    :param max_c: 车的容量，转换为件箱的数量
    :param tr: 栈板转换系数
    :return: car:每辆车装载的货物量
    job_re:记录每辆车装载的货物编号
    '''
    car = []
    s = 0
    car_num = 0
    sub_car = []
    job_re = []
    sub_job_re = []
    re_job = []
    # f_p = [0.1, 0.15]
    # max_c = [300, 360]
    # tr = [15, 18]
    r_j = 0
    c = 0
    ch = 0
    sub_job = []
    sub_re = []

    for i in range(len(job_data)):
        # c = 0
        # sub_car = []
        # sub_job_re = []
        u_sub_car = []
        u_sub_job_re = []
        for j in range(len(job_data[i])):
            c = 0
            sub_car = []
            sub_job_re = []
            for k in range(len(job_data[i][j])):
                if job_type[i][j][k] != 0:
                    ch = job_data[i][j][k]
                else:
                    ch = job_data[i][j][k] * tr[i]
                m_c = max_c[i]
                while True:
                    if c + ch <= m_c:
                        # print("hello")
                        c += ch
                        sub_car.append(ch)
                        sub_job_re.append([i, j, k])

                        if c == m_c:
                            sub_job.append(sub_car)
                            sub_re.append(sub_job_re)
                            sub_car = []
                            sub_job_re = []
                            c = 0
                            break

                        if k + 1 == len(job_data[i][j]):
                            sub_job.append(sub_car)
                            sub_re.append(sub_job_re)
                            sub_car = []
                            sub_job_re = []
                            c = 0

                        break
                    elif c < m_c and c + ch > m_c:
                        if k + 1 == len(job_data[i][j]):
                            if c + ch <= m_c * (1 + f_p[i]):
                                # print("hello")
                                sub_car.append(ch)
                                sub_job_re.append([i, j, k])
                                sub_job.append(sub_car)
                                sub_re.append(sub_job_re)

                                # car.append(sub_car)
                                # job_re.append(sub_job_re)
                                break
                            else:
                                if job_type[i][j][k] != 0:
                                    # print("hello")
                                    sub_car.append(m_c - c)
                                    sub_job_re.append([i, j, k])
                                    sub_job.append(sub_car)
                                    sub_re.append(sub_job_re)

                                    # car.append(sub_car)
                                    # job_re.append(sub_job_re)
                                    sub_car = []
                                    sub_job_re = []
                                    ch = ch - (m_c - c)
                                    c = 0
                                else:
                                    # print("hello")
                                    rr = (m_c - c) // tr[i]
                                    sub_car.append(rr * tr[i])
                                    sub_job_re.append([i, j, k])
                                    sub_job.append(sub_car)
                                    sub_re.append(sub_job_re)

                                    # car.append(sub_car)
                                    # job_re.append(sub_job_re)
                                    sub_car = []
                                    sub_job_re = []
                                    ch = ch - rr * tr[i]
                                    c = 0

                        else:
                            if job_type[i][j][k] == 0:
                                # print("hello")
                                rr = (m_c - c) // tr[i]
                                sub_car.append(rr * tr[i])
                                sub_job_re.append([i, j, k])
                                sub_job.append(sub_car)
                                sub_re.append(sub_job_re)

                                # car.append(sub_car)
                                # job_re.append(sub_job_re)
                                sub_car = []
                                sub_job_re = []
                                ch = ch - rr * tr[i]
                                c = 0
                            else:
                                # print("hello")
                                sub_car.append(m_c - c)
                                sub_job_re.append([i, j, k])
                                sub_job.append(sub_car)
                                sub_re.append(sub_job_re)

                                # car.append(sub_car)
                                # job_re.append(sub_job_re)
                                sub_car = []
                                sub_job_re = []
                                ch = ch - (m_c - c)
                                c = 0

            u_sub_car.append(sub_job)
            u_sub_job_re.append(sub_re)
            sub_job = []
            sub_re = []

        car.append(u_sub_car)
        job_re.append(u_sub_job_re)



    # for i in range(len(job_re)):
    #     if n - 1 == job_re[i][0][0]:
    #         s = i
    job_total = []
    job_sub = []
    job_sub_sub = []
    job_type_total = []
    type_sub = []
    type_sub_sub = []
    for i in range(len(job_re)):
        if i < n:
            job_sub = []
            type_sub = []
            for j in range(len(job_re[i])):
                # e = 0
                # m = 0
                # p_type = []
                # type_sub_sub = []
                # job_sub_sub = []
                u_job_sub = []
                u_type_sub = []
                for q in range(len(job_re[i][j])):
                    e = 0
                    m = 0
                    p_type = []
                    type_sub_sub = []
                    job_sub_sub = []
                    for k in range(len(job_re[i][j][q])):
                        if job_type[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]] == 0:
                            m += int(car[i][j][q][k] / tr[i])
                            p_type.append(0)
                        elif job_type[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]] == 1:
                            e += car[i][j][q][k]
                            p_type.append(1)
                        elif job_type[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]] == 2:
                            e += car[i][j][q][k]
                            p_type.append(2)

                    if (1 in p_type) or (2 in p_type):
                        type_sub_sub.append(1)
                        job_sub_sub.append(e)

                    if 0 in p_type:
                        type_sub_sub.append(0)
                        job_sub_sub.append(m)

                    u_job_sub.append(job_sub_sub)
                    u_type_sub.append(type_sub_sub)
                job_sub.append(u_job_sub)
                type_sub.append(u_type_sub)
            job_total.append(job_sub)
            job_type_total.append(type_sub)

    return car, job_re, job_total, job_type_total

def se_solve(job_data_se, d_list_se, data_start_se, V_j, t):
    '''
    该函数用于求解自制任务
    :param job_data_se: 自制任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量
    :param d_list_se: 各个自制货物的截止日期
    :param data_start_se: 各个自制任务对应的开始时间
    :param V_j: 不同类型货物对应通道的速度，数量/分钟，0的位置对应栈板，1的位置对应件箱，2的位置对应自制
    :param t: 求解时间，若最后无解，则需调大时间
    :return:solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为分钟
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    '''
    # V_j = [2, 17, 3]
    t_t_list = [i * 2 * 60 for i in range(5, 12)]
    total_C_list = []
    total_C_se_list = []
    bool_job_list = []
    bool_job_se_list = []
    bool_sub_job_list = []
    bool_sub_job_se_list = []
    job_p_list = []
    job_p_se_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    de = []
    total_b = 0
    total_bb = 0
    model = cp_model.CpModel()
    max_time = cp_model.INT32_MAX

    for i in range(len(job_data_se)):
        j_b_se = model.NewBoolVar('%d' % i)
        total_bb += j_b_se
        bool_job_se_list.append(j_b_se)
        u_job_p_se_sub = []
        u_C_se_list = []
        u_bool_sub_job_se = []
        uuu_bool_sub_job_se = []
        for j in range(len(job_data_se[i])):
            u_j_sub_b_se = model.NewBoolVar('%d_%d' % (i, j))
            u_bool_sub_job_se.append(u_j_sub_b_se)
            job_p_se_sub = []
            C_se_list = []
            bool_sub_job_se = []
            uu_bool_sub_job_se = []
            for k in range(len(job_data_se[i][j])):
                j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))
                bool_sub_job_se.append(j_sub_b_se)
                total_b += j_sub_b_se
                sub_c_se_list = []
                sub_p_se_list = []
                j_sub_p_se_s = model.NewIntVar(data_start_se[i], 1440, 'p_s_%d_%d_%d' % (i, j, k))
                j_sub_p_se_e = model.NewIntVar(data_start_se[i], 1440, 'p_e_%d_%d_%d' % (i, j, k))
                j_sub_p_e_se_1 = model.NewIntVar(data_start_se[i], 1440, 'p_e1_%d_%d_%d' % (i, j, k))
                due_data_se_d = model.NewBoolVar('due_data_d')
                c_se_d = model.NewBoolVar('c_d')
                model.Add(j_sub_p_se_e <= d_list_se[i]).OnlyEnforceIf(due_data_se_d)
                model.Add(j_sub_p_se_e > d_list_se[i]).OnlyEnforceIf(due_data_se_d.Not())
                sub_p_se_list.append(j_sub_p_se_s)
                sub_p_se_list.append(j_sub_p_se_e)
                sub_p_se_list.append(j_sub_p_e_se_1)
                job_p_se_sub.append(sub_p_se_list)
                b = model.NewBoolVar('%d_%d_%d' % (i, j, 8))
                sub_c_se_list.append(b)

                model.Add(sum(sub_c_se_list) > 0).OnlyEnforceIf(c_se_d)
                model.Add(sum(sub_c_se_list) == 0).OnlyEnforceIf(c_se_d.Not())
                model.Add(due_data_se_d == 1).OnlyEnforceIf(c_se_d)
                model.Add(c_se_d + due_data_se_d == 2).OnlyEnforceIf(j_sub_b_se)
                model.Add(c_se_d + due_data_se_d < 2).OnlyEnforceIf(j_sub_b_se.Not())
                C_se_list.append(sub_c_se_list)
            u_job_p_se_sub.append(job_p_se_sub)
            u_C_se_list.append(C_se_list)
            model.Add(sum(bool_sub_job_se) == len(bool_sub_job_se)).OnlyEnforceIf(u_j_sub_b_se)
            model.Add(sum(bool_sub_job_se) < len(bool_sub_job_se)).OnlyEnforceIf(u_j_sub_b_se.Not())
            # uu_bool_sub_job_se.append(bool_sub_job_se)
            uuu_bool_sub_job_se.append(bool_sub_job_se)
        model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_b_se)
        model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_b_se.Not())
        total_C_se_list.append(u_C_se_list)
        bool_sub_job_se_list.append(uuu_bool_sub_job_se)
        job_p_se_list.append(u_job_p_se_sub)


    for i in range(len(job_data_se)):
        # total_interval_se = 0
        # x_t_intervals_se = []
        for j in range(len(job_data_se[i])):
            # total_interval_se = 0
            x_t_intervals_se = []
            for q in range(len(job_data_se[i][j])):
                total_interval_se = 0
                # x_t_intervals_se = []
                for k in range(len(total_C_se_list[i][j][q])):
                    total_interval_se += total_C_se_list[i][j][q][k] * V_j[2]
                t_ii = model.NewIntVar(1, 999999, 't_ii_%d' % j)
                model.Add(t_ii == total_interval_se + 1)
                I_se = model.NewIntVar(0, 999999, 'In_%d' % j)
                model.AddDivisionEquality(I_se, sum(job_data_se[i][j][q]), t_ii)
                j_sub_p_I_se_intervals = model.NewOptionalIntervalVar(job_p_se_list[i][j][q][0], I_se * 2 + 30, job_p_se_list[i][j][q][2],
                                                                   bool_sub_job_se_list[i][j][q], '%d_%d_%d_I' % (i, j, q))
                x_t_intervals_se.append(j_sub_p_I_se_intervals)
                # de.append(int(3))
                y_end = model.NewIntVar(0, 10, 'y_end_%d%d%d%d' % (i, j, q, 8))
                j_sub_p_se_intervals = model.NewOptionalIntervalVar(job_p_se_list[i][j][q][0], I_se * 2 + 1, job_p_se_list[i][j][q][1],
                                                                 total_C_se_list[i][j][q][0], 'p_%d_%d_%d' % (i, j, q))
                j_sub_c_se_intervals = model.NewOptionalIntervalVar(7, 1, y_end,
                                                                 total_C_se_list[i][j][q][0], 'c_%d_%d_%d' % (i, j, q))
                x_intervals.append(j_sub_p_se_intervals)
                y_intervals.append(j_sub_c_se_intervals)

            model.AddNoOverlap(x_t_intervals_se)
    model.AddNoOverlap2D(x_intervals, y_intervals)

    model.Maximize(total_bb)
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8
    solver.parameters.max_time_in_seconds = t
    # solver.parameters.log_search_progress = True
    status = solver.Solve(model)

    if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
        print("status: ", status)


        for i in range(len(job_p_se_list)):
            solu_x_sub_se = []
            for j in range(len(job_p_se_list[i])):
                u_solution_x_se = []
                for k in range(len(job_p_se_list[i][j])):
                    solution_x_se = []
                    solution_x_se.append(solver.Value(job_p_se_list[i][j][k][0]))
                    solution_x_se.append(solver.Value(job_p_se_list[i][j][k][1]))
                    u_solution_x_se.append(solution_x_se)
                solu_x_sub_se.append(u_solution_x_se)
            solution_x_total.append(solu_x_sub_se)


        for i in range(len(bool_sub_job_se_list)):
            solu_bool_sub_se = []
            for j in range(len(bool_sub_job_se_list[i])):
                u_solu_bool_sub_se = []
                for k in range(len(bool_sub_job_se_list[i][j])):
                    u_solu_bool_sub_se.append(solver.Value(bool_sub_job_se_list[i][j][k]))
                solu_bool_sub_se.append(u_solu_bool_sub_se)
            solution_bool_sub_job.append(solu_bool_sub_se)


        for i in range(len(bool_sub_job_se_list)):
            solu_C_se_sub = []
            for j in range(len(bool_sub_job_se_list[i])):
                solu_C_sub_sub_se = []
                for p in range(len(bool_sub_job_se_list[i][j])):
                    u_solu_C_sub_sub_se = []
                    for k in range(len(total_C_se_list[i][j][p])):
                        u_solu_C_sub_sub_se.append(solver.Value(total_C_se_list[i][j][p][k]))
                    solu_C_sub_sub_se.append(u_solu_C_sub_sub_se)
                solu_C_se_sub.append(solu_C_sub_sub_se)
            solution_bool_C.append(solu_C_se_sub)

        print("youjie")
    else:
        print('No solution found.')

    return solution_x_total, solution_bool_sub_job, solution_bool_C

def solve(job_data, d_list, job_type, data_end_start, sxt, sbsj, sbc, V_j, t):
    """
    该函数用于求解时间窗，输入输出参数解释如下
    :param job_data:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
    :param d_list:EMS货物的截止日期
    :param job_type:EMS货物形态 0可代表栈板，1代表件箱，2代表gtp
    :param data_end_start:各个任务对应的开始时间
    :param sxt:所有自制子任务的开始处理时间和处理结束时间，单位为分钟
    :param sbsj:该项对应某一个自制子任务是否被处理，若为1则被处理，若为0则没被处理
    :param sbc:该项对应自制子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    :param V_j: 不同类型货物对应通道的速度，数量/分钟，0的位置对应栈板，1的位置对应件箱，2的位置对应自制
    :param t:求解时间，若最后无解，则需调大时间
    :return: solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为分钟
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    """

    # V_j = [2, 17, 3]
    t_t_list = [i * 2 * 60 for i in range(5, 12)]
    total_C_list = []
    total_C_se_list = []
    bool_job_list = []
    bool_job_se_list = []
    bool_sub_job_list = []
    bool_sub_job_se_list = []
    job_p_list = []
    job_p_se_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    de = []
    rs_c = []
    total_b = 0
    total_bb = 0
    total_bbb = 0

    model = cp_model.CpModel()
    max_time = cp_model.INT32_MAX
    print("job_data: ", job_data)
    # print("d: ", d)

    for i in range(len(job_data)):
        ts = data_end_start[i]
        j_b = model.NewBoolVar('%d' % i)
        total_bb += j_b
        bool_job_list.append(j_b)
        job_p_sub = []
        C_list = []
        bool_sub_job = []
        # bool_ssub_job = []
        bool_sub_ssub_job = []
        for j in range(len(job_data[i])):
            j_sub_b = model.NewBoolVar('%d_%d' % (i, j))
            bool_sub_job.append(j_sub_b)
            u_bool_sub_sub_job = []
            # bool_sub_ssub_job = []
            u_job_p_sub_sub = []
            u_sub_C_list = []
            u_bool_sub_job_se = []
            for k in range(len(job_data[i][j])):
                u_j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))
                u_bool_sub_job_se.append(u_j_sub_b_se)

                bool_sub_sub_job = []
                job_p_sub_sub = []
                sub_C_list = []
                for p in range(len(job_data[i][j][k])):
                    j_sub_sub_b = model.NewBoolVar('%d_%d_%d_%d' % (i, j, k, p))
                    bool_sub_sub_job.append(j_sub_sub_b)
                    total_bbb += j_sub_sub_b
                    sub_sub_c_list = []
                    sub_sub_p_list = []
                    j_sub_p_s = model.NewIntVar(ts, 1440, 'p_s_%d_%d_%d_%d' % (i, j, k, p))
                    j_sub_p_e = model.NewIntVar(ts, 1440, 'p_e_%d_%d_%d_%d' % (i, j, k, p))
                    j_sub_p_e_1 = model.NewIntVar(ts, 1440, 'p_e1_%d_%d_%d_%d' % (i, j, k, p))
                    due_data_d = model.NewBoolVar('due_data_d')
                    c_d = model.NewBoolVar('c_d')
                    model.Add(j_sub_p_e <= d_list[i]).OnlyEnforceIf(due_data_d)
                    model.Add(j_sub_p_e > d_list[i]).OnlyEnforceIf(due_data_d.Not())
                    sub_sub_p_list.append(j_sub_p_s)
                    sub_sub_p_list.append(j_sub_p_e)
                    sub_sub_p_list.append(j_sub_p_e_1)
                    job_p_sub_sub.append(sub_sub_p_list)
                    if job_type[i][j][k][p] == 0:
                        b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, 7))
                        sub_sub_c_list.append(b)
                    else:
                        for m in range(6):
                            b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                            sub_sub_c_list.append(b)

                    model.Add(sum(sub_sub_c_list) > 0).OnlyEnforceIf(c_d)
                    model.Add(sum(sub_sub_c_list) == 0).OnlyEnforceIf(c_d.Not())
                    model.Add(due_data_d == 1).OnlyEnforceIf(c_d)
                    model.Add(c_d + due_data_d == 2).OnlyEnforceIf(j_sub_sub_b)
                    model.Add(c_d + due_data_d < 2).OnlyEnforceIf(j_sub_sub_b.Not())
                    sub_C_list.append(sub_sub_c_list)
                u_job_p_sub_sub.append(job_p_sub_sub)
                u_sub_C_list.append(sub_C_list)
                u_bool_sub_sub_job.append(bool_sub_sub_job)
                model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se)
                model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se.Not())

            model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b)
            model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b.Not())

            C_list.append(u_sub_C_list)
            bool_sub_ssub_job.append(u_bool_sub_sub_job)
            job_p_sub.append(u_job_p_sub_sub)
            # model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b)
            # model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b.Not())

        model.Add(sum(bool_sub_job) == len(bool_sub_job)).OnlyEnforceIf(j_b)
        model.Add(sum(bool_sub_job) < len(bool_sub_job)).OnlyEnforceIf(j_b.Not())

        total_C_list.append(C_list)
        bool_sub_job_list.append(bool_sub_ssub_job)
        job_p_list.append(job_p_sub)


    # for x in range(len(t_t_list)):
    #     x_s = model.NewConstant(int(t_t_list[x] - 48))
    #     ii = model.NewConstant(48)
    #     x_e = model.NewConstant(t_t_list[x])
    #     y_s = model.NewConstant(0)
    #     iii = model.NewConstant(7)
    #     y_e = model.NewConstant(7)
    #     x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % x)
    #     y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % x)
    #     x_intervals.append(x_ii)
    #     y_intervals.append(y_ii)

    for g in range(len(sxt)):
        for i in range(len(sxt[g])):
            for k in range(len(sxt[g][i])):
                x_s = model.NewConstant(sxt[g][i][k][0])
                ii = model.NewConstant(sxt[g][i][k][1] - sxt[g][i][k][0])
                x_e = model.NewConstant(sxt[g][i][k][1])
                y_s = model.NewConstant(7)
                iii = model.NewConstant(1)
                y_e = model.NewConstant(8)
                # print("sbsj[g][i]: ", sbsj[g][i])
                if sbsj[g][i][k] == 1:
                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k], 'x_ii%d' % i)
                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k], 'y_ii%d' % i)
                    x_intervals.append(x_ii)
                    y_intervals.append(y_ii)
                    de.append(V_j[2])
                    rs_c.append(x_ii)

    for i in range(len(job_data)):
        # total_interval = 0
        x_t_intervals = []
        for j in range(len(job_data[i])):
            x_tt_intervals = []
            # ini = []
            # cd = []
            # mm_v = model.NewIntVar(0, 1440, 'p_e_%d_%d' % (i, j))
            for e in range(len(job_data[i][j])):
                ini = []
                cd = []
                mm_v = model.NewIntVar(0, 1440, 'p_e_%d_%d' % (i, j))
                for p in range(len(job_data[i][j][e])):
                    total_interval = 0
                    for k in range(len(total_C_list[i][j][e][p])):
                        total_interval += total_C_list[i][j][e][p][k] * V_j[job_type[i][j][e][p]]
                    t_i = model.NewIntVar(1, 999999, 't_i_%d' % j)
                    model.Add(t_i == total_interval + 1)
                    I = model.NewIntVar(0, 999999, 'In_%d' % j)
                    model.AddDivisionEquality(I, job_data[i][j][e][p], t_i)
                    # j_sub_p_I_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][p][0], I + 30, job_p_list[i][j][p][2],
                    #                                                    bool_sub_job_list[i][j][p], '%d_%d_I' % (i, j))
                    # model.Add(job_p_list[i][j][p][0] + I + 30 == job_p_list[i][j][p][2])
                    ini.append(job_p_list[i][j][e][p][0])
                    x_tt_intervals.append(job_p_list[i][j][e][p][2])
                    # model.Add(I == I + 30)
                    cd.append(I)
                    for m in range(len(total_C_list[i][j][e][p])):
                        # de.append(int(17))
                        if job_type[i][j][e][p] == 1:
                            y_end = model.NewIntVar(1, 6, 'y_end_%d%d%d' % (i, j, m))
                            j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I * 2 + 1, job_p_list[i][j][e][p][1],
                                                                             total_C_list[i][j][e][p][m], 'p_%d_%d_%d_%d' % (i, j, p, m))
                            j_sub_c_intervals = model.NewOptionalIntervalVar(m, 1, y_end,
                                                                             total_C_list[i][j][e][p][m], 'c_%d_%d_%d_%d' % (i, j, p, m))
                        else:
                            y_end = model.NewIntVar(1, 8, 'y_end_%d%d%d' % (i, j, m))
                            j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I * 2 + 1, job_p_list[i][j][e][p][1],
                                                                             total_C_list[i][j][e][p][m], 'p_%d_%d_%d_%d' % (i, j, p, m))
                            j_sub_c_intervals = model.NewOptionalIntervalVar(6, 1, y_end,
                                                                             total_C_list[i][j][e][p][m], 'c_%d_%d_%d_%d' % (i, j, p, m))

                        if job_type[i][j][e][p] == 1:
                            rs_c.append(j_sub_p_intervals)
                            de.append(int(V_j[1]))
                        x_intervals.append(j_sub_p_intervals)
                        y_intervals.append(j_sub_c_intervals)
                # model.Add(mm_v == max(x_tt_intervals))
                # model.AddMaxEquality(mm_v, x_tt_intervals)
                if len(ini) == 2:
                    model.Add(ini[0] == ini[1])
                    model.Add(bool_sub_job_list[i][j][e][0] == bool_sub_job_list[i][j][e][1])
                    I_v = model.NewIntVar(0, 99999, 'p_e_%d_%d' % (i, j))
                    model.AddMaxEquality(I_v, cd)
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], I_v * 2 + 31, mm_v,
                                                                       bool_sub_job_list[i][j][e][0], '%d_%d_I' % (i, j))
                    x_t_intervals.append(j_sub_p_I_intervals)
                else:
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], cd[0] * 2 + 31, mm_v,
                                                                       bool_sub_job_list[i][j][e][0], '%d_%d_I' % (i, j))
                    x_t_intervals.append(j_sub_p_I_intervals)


            model.AddNoOverlap(x_t_intervals)

    model.AddNoOverlap2D(x_intervals, y_intervals)
    model.AddCumulative(rs_c, de, 84)

    # for i in range(len(job_data) - 1):
    #     model.Add(bool_job_list[i] == 1).OnlyEnforceIf(bool_job_list[i + 1])

    model.Maximize(total_bbb)
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8
    solver.parameters.max_time_in_seconds = t
    # solver.parameters.log_search_progress = True
    status = solver.Solve(model)

    if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
        print("status: ", status)
        for i in range(len(job_data)):
            solu_x_sub = []
            for j in range(len(job_data[i])):
                u_solu_x_sub = []
                for g in range(len(job_data[i][j])):
                    so = []
                    for k in range(len(job_data[i][j][g])):
                        solution_x = []
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][0]))
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][1]))
                        so.append(solution_x)
                    u_solu_x_sub.append(so)
                solu_x_sub.append(u_solu_x_sub)
            solution_x_total.append(solu_x_sub)

        # solution_x_total = solution_x_total


        for i in range(len(job_data)):
            solu_bool_sub = []
            for j in range(len(job_data[i])):
                u_solu_bool_sub = []
                for g in range(len(job_data[i][j])):
                    so = []
                    for k in range(len(job_data[i][j][g])):
                        so.append(solver.Value(bool_sub_job_list[i][j][g][k]))
                    u_solu_bool_sub.append(so)
                solu_bool_sub.append(u_solu_bool_sub)
            solution_bool_sub_job.append(solu_bool_sub)

        # solution_bool_sub_job = solution_bool_sub_job + sbsj



        for i in range(len(job_data)):
            solu_C_sub = []
            for j in range(len(job_data[i])):
                solu_C_sub_sub = []
                for e in range(len(job_data[i][j])):
                    u_solu_C_sub_sub = []
                    for p in range(len(job_data[i][j][e])):
                        so = []
                        for k in range(len(total_C_list[i][j][e][p])):
                            so.append(solver.Value(total_C_list[i][j][e][p][k]))
                        u_solu_C_sub_sub.append(so)
                    solu_C_sub_sub.append(u_solu_C_sub_sub)
                solu_C_sub.append(solu_C_sub_sub)
            solution_bool_C.append(solu_C_sub)

        # solution_bool_C = solution_bool_C + sbc


        print("youjie")
    else:
        print('No solution found.')

    return solution_x_total, solution_bool_sub_job, solution_bool_C


if __name__ == '__main__':

    V_j = [5, 16, 2]

    zz_goods_num = [[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]], [[2, 114], [30]]]
    zz_end_time = [960, 960]
    zz_begin_time = [480, 480]
    zz_job_type = [[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]], [[1, 1], [1]]]

    ems_goods_num = [
        [[22, 400], [400, 22]],
        [[290, 15, 106, 105, 5, 90, 75], [501, 49, 2, 2, 400, 500, 47, 300, 10, 5, 30, 100, 100, 10, 10,
         50, 110, 80, 80, 110, 5, 90, 400, 20, 297, 100, 90, 90, 48, 2, 2, 50, 150, 180, 5, 10]]]
    ems_end_time = [1080, 1080]
    ems_begin_time = [480, 480]
    ems_job_type = [
        [[1, 1], [1, 1]],
        [[1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
         1, 1, 1, 1, 0, 1, 0, 1]]]
    fu_dong = [0.1, 0.1, 0.1, 0.08]
    rong_liang = [300, 300, 300, 300]
    zhuan_hua = [10, 10, 10, 10]


    car, job_re, job_total, job_type_total = load_fun_3(ems_goods_num + zz_goods_num, ems_job_type + zz_job_type,
                                                        len(ems_goods_num),
                                                        fu_dong, rong_liang, zhuan_hua)

    print("car: ", car)
    print("job_re: ", job_re)

    print("job_total: ", job_total)
    print("job_type_total: ", job_type_total)

    print("car[len(ems_goods_num):]: ", car[len(ems_goods_num):])
    sxt, sbsj, sbc = se_solve(car[len(ems_goods_num):], zz_end_time, zz_begin_time, V_j, 60.0)
    print("sxt: ", sxt)
    print("sbsj: ", sbsj)
    print("sbc: ", sbc)

    solution_x_total, solution_bool_sub_job, solution_bool_C = solve(job_total, ems_end_time, job_type_total,
                                                                     ems_begin_time,
                                                                     sxt, sbsj, sbc, V_j, 300.0)

    print("solution_x_total: ", solution_x_total)
    print("solution_bool_sub_job: ", solution_bool_sub_job)
    print("solution_bool_C: ", solution_bool_C)









